#!/bin/sh
# see also /sbin scripts: usablefs, set_plang, switch
#

######################## localization ########################
L_DONE="done"
L_FAILED="failed"
L_ERROR_IS_TOO_CRITICAL="Error is too critical, dropping out to console..."
L_LOADING_KEYBOARD_LAYOUT="Loading '%s' keyboard layout..." #printf
L_DROPPED_TO_INITRD_SHELL="Dropped to initramfs shell. Type 'exec switch' to continue booting Puppy."
L_DEBUG_SAVE="To save debug info to a partition, type 'debugsave'"
##############################################################

if ! mount &>/dev/null ; then
	/sbin/usablefs # mount: /proc /sys /dev / (proc sysfs devtmpfs rootfs)
fi

export TERM="xterm"
export TERMINFO="/usr/share/terminfo"
export LANG=C
PATH="/bin:/sbin"
export KERNELVER="$(uname -r)"
VFAT_OUT_PARAM='shortname=mixed,quiet,utf8' #see also /sbin/set_plang
. /DISTRO_SPECS #v412 has DISTRO_VERSION, DISTRO_FILE_PREFIX
. /etc/rc.d/functions_x

if [ $loglevel ] ; then
  LOGLEVEL=$loglevel
else
  echo '3' > /proc/sys/kernel/printk
fi

case $(uname -m) in arm*) ARM_SYSTEM=yes ;; esac

#=============================================================
#                        FUNCTIONS
#=============================================================

check_status() { # "$1" - status value - ex: 0"
	[ "$1" ] || return
	if [ $1 -eq 0 ] ;then
		echo -en "\\033[74G" >/dev/console #move to column 72. 110426: 74
		echo -e "\\033[1;32m${L_DONE}\\033[0;39m" >/dev/console #32=green
	else
		echo -en "\\033[72G" >/dev/console #move to column 72.
		echo -e "\\033[1;31m${L_FAILED}\\033[0;39m" >/dev/console #31=red
	fi
}

fatal_error() { # "$1" - message - ex: "Something failed"
	echo -en "\\033[1;35m" >/dev/console #35=purple
	echo "*** $1"
	echo "*** $1" >/dev/console
	echo "*** ${L_ERROR_IS_TOO_CRITICAL}" >/dev/console
	echo -en "\\033[0;39m" >/dev/console
	echo -e "\\033[1;32m*** $L_DEBUG_SAVE\\033[0;39m" >/dev/console #added
	exec /bin/sh >/dev/console 2>&1
}

ensure_mounted() {
	# "$1" - partition - ex: sda3
	# "$2" - mountpoint - ex: /mnt/pdrv
	ONE_MP="$(mount | grep -m1 "/dev/${1} " | cut -f 3 -d ' ')"
	[ "$ONE_MP" ] && return
	ONE_FS="$(echo "$HAVE_PARTS" | grep -m1 "${1}|" | cut -f 2 -d '|')"
	ONE_MP="${2}"
	MNT_DEV=/dev/${1}
	[ -d "$ONE_MP" ] || mkdir -p $ONE_MP
	MNT_DSK=$(fx_get_drvname $1)
	#--
	MNT_O="-o noatime"
	if [ "$ONE_FS" = "ext4" -a -e /sys/block/${MNT_DSK}/queue/rotational ] ; then
		if [ "$(cat /sys/block/${MNT_DSK}/queue/rotational)" = "0" ] ; then
			# enable SSD TRIM
			MNT_O="-o discard,noatime"
		fi
	fi
	#--
	[ "$PFSCKP" = "yes" ] && e2fsck -y "$MNT_DEV" > /dev/console 2>&1
	echo "Mounting $MNT_DEV on $ONE_MP as $ONE_FS."
	mount -t $ONE_FS $MNT_O $MNT_DEV $ONE_MP
	[ $? -ne 0 ] && { echo "${1} on $ONE_MP as $ONE_FS mount failed."; ONE_MP=""; return 1; }
	# fsckme.flg is created by rc.sysinit and deleted by rc.shutdown
	if [ -f ${ONE_MP}/fsckme.flg ] ; then # improper shutdown
		# flsckme.flg = improper shutdown or something wrong with fs (rc.sysinit)
		IFS="," read PDEV DEVFS SAVEFILE < ${ONE_MP}/fsckme.flg #ex: sdb1,ext3,
		if [ "$PDEV" = "$PDRV" ] && [ "$SAVEFILE" = "" ] ; then
			rm -f /fsckme.flg
			[ "$PFSCKP" = "yes" ] && return # boot param, partition already fsck'ed
			e2fsck -y /dev/${FSCK_PART} > /dev/console 2>&1
			ensure_mounted "$1" "$2"
		fi
	fi
}

get_part_info() {
 probedisk -hr > /tmp/probedisk.log
 probepart -hr > /tmp/probepart.log
 sed 's%|.*%% ; s%.*/%%' /tmp/probedisk.log > /tmp/ALLDRVS0
 HAVE_PARTS="$(cat /tmp/probepart.log | cut -f 1-2 -d '|' | sed -e 's%/dev/%%')"
 [ "$PDEBUG" ] && echo "$HAVE_PARTS" > /tmp/HAVE_PARTS
}

#=============================================================
#                           MAIN
#=============================================================

clear #clear the screen.

[ ! "$LOGLEVEL" ] && exec 1>/tmp/bootinit.log 2>&1 #remove o/p from console. v2.22 loglevel added.

[ $pdrv ] && PDRV=$pdrv   #boot parameter, partition have booted off. ex: hda3
[ $pdev1 ] && PDRV=$pdev1 #boot parameter, partition have booted off. ex: hda3
[ $root ] && PDRV=$root   #boot parameter, partition have booted off
[ $rootdev ] && PDRV=$rootdev   #boot parameter, partition have booted off
[ $pmedia ] && PMEDIA=$pmedia

RDSH=""
if [ "$pfix" ];then
 for ONEFIX in $(echo -n "$pfix" | tr ',' ' ')
 do
  case $ONEFIX in
   rdsh)    RDSH="yes";;          #exit to shell in initial ramdisk.
   xorgwizard) PXORGWIZARD="yes";;#force xorgwizard for this session
   nox)     PNOX="yes";;          #do not start X.
   fsck)    PFSCKP="yes";;        #do fsck before first mount of ext partitions
   fsckp)   PFSCKP="yes";;        #do fsck before first mount of ext partitions
   *)       echo "pfix=$ONEFIX is not a known boot parameter for a full install";;
  esac
 done
fi

if [ "$ARM_SYSTEM" != "yes" ] ; then
	[ "$TZ" ] && export TZ
	hwclock -l -s
fi

#-----------------------------
# see if actually a non-huge kernel is being used..
not_a_huge_kernel_stuff && check_status 0
#-----------------------------

get_part_info
grep -v '^sr' /tmp/ALLDRVS0 > /tmp/ATADRIVES0
ATAOPTICALDRIVES="$(grep '^sr' /tmp/ALLDRVS0 | tr '\n' ' ')"

# process PDRV
if [ ! "$PDRV" ] ; then
	for i in $(cat /proc/cmdline) ; do
		case $i in "root="*) PDRV=${i#root=} ;; esac
	done
fi
case $PDRV in
	UUID=*) PDRV=${PDRV#UUID=} ;; #remove leading UUID=
	PARTUUID=*) fatal_error "Sorry PARTUUID= is not supported. Use root=UUID=<uuid> instead" ;;
	*/*) PDRV=${PDRV##*/} ;; #$(basename $PDRV) 
esac
#${PDRV}=$(decode_id $PDRV) #decode UUID, LABEL
if [ "$(echo -n ${PDRV} | grep -E '^[a-z]+[0-9]')" -a "$(grep -m1 " ${PDRV}$" /proc/partitions)" ];then
	ok=1 #is a real partition
else
	PDRV="$(blkid | grep -m1 -E " LABEL=.${PDRV}| UUID=.${PDRV}" | cut -f1 -d: | cut -f3 -d/)" #is LABEL or UUID
fi

# if trapped in the initrd, you can specify the correct PDRV and reexec /init
# ex: echo sda3 > /tmp/override_pdrv
[ -f /tmp/override_pdrv ] && PDRV="$(cat /tmp/override_pdrv)"

# PDRV must be a linux fs
FSTYPE="$(blkid /dev/$PDRV | grep -o ' TYPE=.*' | cut -f 2 -d '"')"
case $FSTYPE in 
	ext2|ext3|ext4|reiserfs|minix|f2fs) ok=1 ;;
	*) fatal_error "/dev/${PDRV}: Partition must be ext2/ext3/ext4..." ;;
esac

# mount PDRV
ensure_mounted $PDRV /pup_new || fatal_error "Could not mount $PDRV ..."

#-----------------------------------------
. /pup_new/etc/DISTRO_SPECS
echo -en "\\033[0;34m***\\033[0;37m ${DISTRO_NAME} ${DISTRO_VERSION}" > /dev/console
echo -en "\\033[0;34m -\\033[0;37m Linux ${KERNELVER} " > /dev/console
echo -en "\\033[0;31m[\\033[0;37m`uname -m`\\033[0;31m]" > /dev/console
echo -e "\\033[0;34m ***\\033[0;39m" > /dev/console

# sets PLANG, PKEYS, VFAT_OUT_PARAM, FONTMAP, KMAP, CODEPAGE
[ -f /sbin/set_plang ] && . /sbin/set_plang
#-----------------------------------------

# is it a valid full install?
for i in etc/DISTRO_SPECS etc/rc.d/PUPSTATE ; do
  [ -e /pup_new/${i} ] || fatal_error "File [${PDRV}]/${i} is missing"
done
if ! grep -q 'PUPMODE=2' /pup_new/etc/rc.d/PUPSTATE ; then
  fatal_error "The system in ${PDRV} doesn't look like a full-install OS"
fi

[ "$DEV1FS" ] || DEV1FS=$FSTYPE
[ "$ATADRIVES" ] || ATADRIVES="$(cat /tmp/ATADRIVES0 | tr '\n' ' ')"

mkdir -p /pup_new/etc/rc.d
( # > /pup_new/etc/rc.d/PUPSTATE
echo "PUPMODE=2"
echo "PUP_HOME='/'"
echo "PDEV1='$PDRV'"
echo "DEV1FS='$DEV1FS'"
[ "$PMEDIA" ] && echo "PMEDIA='$PMEDIA'"
echo '#ATADRIVES is all internal ide/pata/sata drives, excluding optical, excluding usb...'
echo "ATADRIVES='$ATADRIVES'"
echo '#ATAOPTICALDRIVES is list of non-usb optical drives...'
echo "ATAOPTICALDRIVES='$ATAOPTICALDRIVES'"
[ -f /sbin/set_plang ] && plang_pupstate #echo
) > /pup_new/etc/rc.d/PUPSTATE

echo -------------------- # debug
mount
echo -------------------- # debug

[ "$PXORGWIZARD" = "yes" ] && touch /pup_new/tmp/xwin_xorgwizard_cli
#PNOX is a boot param. /etc/profile prevents X from starting if this file exists...
[ "$PNOX" = "yes" ] && touch /pup_new/tmp/bootcnt.txt
dmesg > /tmp/dmesg.txt
mkdir -p /pup_new/var/initrd/tmp
cp -af /tmp/* /pup_new/var/initrd/tmp #keep any log files.
cp -af /init* /pup_new/var/initrd
cp -af /sbin/* /pup_new/var/initrd

[ -f /sbin/set_plang ] && plang_copy_to_newroot #$LANG, /etc/keymap|fontmap|codepage

if [ "$RDSH" = "yes" ];then
	echo > /dev/console
	echo "${L_DROPPED_TO_INITRD_SHELL}" > /dev/console
	exec /bin/sh >/dev/console 2>&1
fi

sync
[ -d "/proc/bus/usb" ] && umount /proc/bus/usb
umount /sys
umount /dev
umount /proc

#now using cpio archive for initramfs 'initial ramdisk'...
exec switch_root /pup_new /sbin/init initrd_full_install

### END ###
